package com.cnswhy.cloud.server.app.controller.shop;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.cnswhy.cloud.common.core.exception.BizException;
import com.cnswhy.cloud.common.redis.service.RedisService;
import com.cnswhy.cloud.server.core.constant.RedisConstant;
import com.cnswhy.cloud.server.app.controller.BaseController;
import com.cnswhy.cloud.server.core.dto.*;
import com.cnswhy.cloud.server.core.entity.Customer;
import com.cnswhy.cloud.server.app.exception.LoginExecption;
import com.cnswhy.cloud.server.core.service.shop.ShopProductService;
import com.cnswhy.cloud.server.core.shop.ProductStockService;
import com.cnswhy.cloud.server.core.vo.RespVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

/**
 * 描述: 购物车控制层
 * 版权: Copyright (c) 2019
 * 公司: 小鹿科技
 * 作者: 张润泽
 * 版本: 1.0
 * 创建日期: 2019年8月27日
 * 创建时间: 下午5:35:59
 */
@Api(tags = "购物车控制层,暂时无用")
@Controller
@RequestMapping("/shop/buyerCar")
@Slf4j
public class BuyerCarController extends BaseController {


    @Autowired
    private RedisService redisService;

    @Autowired
    private ShopProductService shopProductService;
    @Autowired
    private ProductStockService productStockService;

    /**
     * 公用静态变量定义(接口成员变量必须初始化值)
     *
     * @author HuangHL
     * @date 2015/12/4
     */
    public interface Constants {

        String USER_LOGIN_FLAG = "currentUser";

        String MERCHANT_LOGIN_FLAG = "currentMerchant";

        String MERCHANT_LOGIN_VERIFYCODE = "merchantLoginVerifyCode";

        /**
         * WEB端导出文件临时路径
         */
        String WEB_DIR_EXPORT = File.separator + "resource" + File.separator + "exportFile" + File.separator;

        /**
         * WEB路径（验证码临时图片库）
         */
        String WEB_DIR_TEMPVCODE = File.separator + "resource" + File.separator + "tempverifyvcode" + File.separator;

        /**
         * 登录时密码输入错误次数
         */
        String USER_SUBMIT_FAILED_COUNT = "userSubmitFailedCount";

        /**
         * 密码错误多少次后锁定账号
         */
        Integer LOCK_ERRORCOUNT_NUMBER = 5;

        /**
         * 用户锁定时长（单位：分）
         */
        Integer LOCK_USER_TIME = 30;

        /**
         * 验证码sessionkey
         */
        String USER_LOGIN_VERIFYCODE = "userLoginVerifyCode";

        /**
         * PC验证码sessionkey
         */
        String CUSTOMER_LOGIN_VERIFYCODE = "customerLoginVerifyCode";

        /**
         * token key的前缀
         */
        String TOKEN_KEY_PRE = "USERTOKEN";

        /**
         *
         */
        String ORGA_FILE_ICON = "/resource/images/common/floder_icon.png";

        String MERCHANT_SUBMIT_FAILED_COUNT = "merchantSubmitFailedCount";

        String MERCHANT_TOKEN_KEY_PRE = "MERTOKEN";

        /**
         * 购物车cookieKey
         */
        String BUYER_CART = "buyer_cart";

    }

    /**
     * 描述：获取购物车所有商品
     * 作者：张润泽
     * 时间：2019年8月27日 下午8:14:58
     *
     * @param request
     * @param response
     * @return
     */
    @ApiOperation(value = "获取购物车所有商品", httpMethod = "POST")
    @RequestMapping("/getCar")
    @ResponseBody
    public RespVo getCar(HttpServletRequest request, HttpServletResponse response) {
        RespVo respVo = new RespVo();
        try {
            // 获取购物车
            BuyerCart buyerCart = this.getBuyerCart(request, response);
            //没有 则创建购物车
            if (null == buyerCart) {
                buyerCart = new BuyerCart();
            }

            //将购物车装满, 前面只是将id装进购物车, 这里还需要查出详情
            List<BuyerMerchant> merchants = buyerCart.getMerchants();
            if (CollUtil.isNotEmpty(merchants)) {
                for (BuyerMerchant merchant : merchants) {
                    //只有购物车中有购物项, 才可以将相关信息加入到购物项中
                    List<BuyerItem> items = merchant.getItems();
                    if (CollUtil.isNotEmpty(items)) {
                        for (BuyerItem buyerItem : items) {
                            ShopProductSku sku = shopProductService
                                    .queryShopProductSku(buyerItem.getSku().getStockId());

                            String ftpPerfix = String.valueOf(
                                    redisService.hget(RedisConstant.SYS_CONFIG_1, RedisConstant.FTP_PATH_PREFIX));
                            if (StringUtils.isNotBlank(sku.getUrl())) {
                                sku.setImgUrl(sku.getUrl());
                            }else if (StringUtils.isNotBlank(sku.getImgUrl())) {
                                sku.setImgUrl(ftpPerfix + sku.getImgUrl());
                            }
                            if (StringUtils.isNotBlank(sku.getThumbnailImg())) {
                                sku.setThumbnailImg(ftpPerfix + sku.getThumbnailImg());
                            }
                            buyerItem.setSku(sku);
                        }
                    }
                }
            }

            respVo.setResult(buyerCart);
            respVo.setCode(RespVo.CODE_SUCCESS);
            respVo.setMessage("成功");
        } catch (Exception e) {
            respVo.setCode(RespVo.CODE_ERROR);
            respVo.setMessage("失败");
            log.error("获取购物车失败", e);
        }
        return respVo;
    }

    /**
     * 描述：获取购物车商品数量
     * 作者：张润泽
     * 时间：2019年8月27日 下午8:14:58
     *
     * @param request
     * @param response
     * @return
     */
    @ApiOperation(value = "获取购物车商品数量")
    @RequestMapping("/getCarNum")
    @ResponseBody
    public RespVo getCarNum(HttpServletRequest request, HttpServletResponse response) {
        RespVo respVo = new RespVo();
        try {
            // 获取购物车
            BuyerCart buyerCart = this.getBuyerCart(request, response);
            int num = 0;
            if (buyerCart != null) {
                num = buyerCart.getTotalNum();
            }

            respVo.setResult(num);
            respVo.setCode(RespVo.CODE_SUCCESS);
            respVo.setMessage("成功");
        } catch (Exception e) {
            respVo.setCode(RespVo.CODE_ERROR);
            respVo.setMessage("失败");
            log.error("获取购物车商品数量失败", e);
        }
        return respVo;
    }

    /**
     * 描述：添加商品
     * 作者：张润泽
     * 时间：2019年8月28日 下午2:38:55
     *
     * @param bo
     * @param request
     * @param response
     * @return
     */
    @RequestMapping("/addItem")
    @ResponseBody
    public RespVo addItem(BuyerOperateBo bo, HttpServletRequest request, HttpServletResponse response) {
        RespVo respVo = new RespVo();
        try {
            if (bo.getMerchantId() == null || bo.getStockId() == null) {
                respVo.setCode(RespVo.VALIDATE_ERROR);
                respVo.setMessage("参数异常");
                return respVo;
            }

            // 添加数量
            int num = bo.getNum() == null ? 1 : bo.getNum();
            try {
                productStockService.subStock(bo.getStockId(),Long.valueOf(num));
            } catch (BizException e) {
                respVo.setCode(RespVo.CODE_ERROR);
                respVo.setMessage("抱歉，库存不足");
                return respVo;
            } catch (Exception e){
                respVo.setCode(RespVo.CODE_ERROR);
                respVo.setMessage("系统繁忙，请稍后重试");
                return respVo;
            }
            // 库存fild
            //String fild = String.valueOf(bo.getStockId());
            // 剩余库存
            /*int stockNum = redisService.hgetInt(RedisConstant.SHOP_PRODUCT_STOCK, fild);
            if (stockNum < num) {
                respVo.setCode(RespVo.CODE_ERROR);
                respVo.setMessage("抱歉，库存不足");
                return respVo;
            }*/

            // 获取购物车
            BuyerCart buyerCart = this.getBuyerCart(request, response);

            // 没有购物车, 创建购物车对象
            if (null == buyerCart) {
                buyerCart = new BuyerCart();
            }

            // 将当前商品追加到购物车
            BuyerMerchant merchant = new BuyerMerchant();
            merchant.setMerchantId(bo.getMerchantId());
            merchant.setMerchantName(bo.getMerchantName());
            // 设置购物项
            BuyerItem item = new BuyerItem();
            ShopProductSku sku = new ShopProductSku();
            sku.setStockId(bo.getStockId());
            item.setSku(sku);
            item.setNum(num);
            merchant.addItem(item);
            //添加商户到购物车
            buyerCart.addMerchant(merchant);

            Customer currentUser = getLoginCustomer( request);
            // 登录了 将购物车放入redis中
            if (currentUser != null) {
                redisService.hset(RedisConstant.BUYER_CAR_KEY, currentUser.getId() + "", buyerCart);
            }
            // 未登录 保存购物车到Cookie中
            else {
                Cookie cookie = new Cookie(Constants.BUYER_CART,
                        URLEncoder.encode(JSON.toJSONString(buyerCart), "UTF-8"));
                //设置path是可以共享cookie
                cookie.setPath("/");
                //设置Cookie过期时间: -1 表示关闭浏览器失效  0: 立即失效  >0: 单位是秒, 多少秒后失效
                cookie.setMaxAge(24 * 60 * 60);
                // Cookie写回浏览器
                response.addCookie(cookie);

                // 返回购物车信息
                respVo.setResult(URLEncoder.encode(JSON.toJSONString(buyerCart), "UTF-8"));
            }
            respVo.setCode(RespVo.CODE_SUCCESS);
            respVo.setMessage("成功");
        } catch (Exception e) {
            respVo.setCode(RespVo.CODE_ERROR);
            respVo.setMessage("失败");
            log.error("添加购物车失败", e);
        }
        return respVo;
    }

    /**
     * 描述：减少商品
     * 作者：张润泽
     * 时间：2019年8月27日 下午8:14:58
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping("/reduceItem")
    @ResponseBody
    public RespVo reduceItem(BuyerOperateBo bo, HttpServletRequest request, HttpServletResponse response) {
        if (bo.getMerchantId() == null || bo.getStockId() == null) {
            return new RespVo(RespVo.VALIDATE_ERROR, "参数异常");
        }

        bo.setNum(1);
        List<BuyerOperateBo> removeList = new ArrayList<BuyerOperateBo>();
        removeList.add(bo);

        return this.removeItem(JSON.toJSONString(removeList), request, response);
    }

    /**
     * 描述：删除商品列表
     * 作者：张润泽
     * 时间：2019年8月27日 下午8:14:58
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping("/removeItem")
    @ResponseBody
    public RespVo removeItem(String removeJson, HttpServletRequest request, HttpServletResponse response) {
        RespVo respVo = new RespVo();
        try {
            if (StringUtils.isBlank(removeJson)) {
                respVo.setCode(RespVo.VALIDATE_ERROR);
                respVo.setMessage("参数异常");
                return respVo;
            }

            // 获取购物车
            BuyerCart buyerCart = this.getBuyerCart(request, response);
            if (buyerCart != null) {
                List<BuyerOperateBo> removeList = JSON.parseArray(removeJson, BuyerOperateBo.class);
                //从购物车移除商品
                buyerCart.deleteItem(removeList);
                Customer loginCustomer = getLoginCustomer( request);
                // 登录了放回redis
                if (loginCustomer != null) {
                    redisService.hset(RedisConstant.BUYER_CAR_KEY, loginCustomer.getId() + "", buyerCart);
                }
                // 未登录放回Cookie
                else {
                    Cookie cookie = new Cookie(Constants.BUYER_CART,
                            URLEncoder.encode(JSON.toJSONString(buyerCart), "UTF-8"));
                    //设置path是可以共享cookie
                    cookie.setPath("/");
                    //设置Cookie过期时间: -1 表示关闭浏览器失效  0: 立即失效  >0: 单位是秒, 多少秒后失效
                    cookie.setMaxAge(24 * 60 * 60);
                    //Cookie写回浏览器
                    response.addCookie(cookie);

                    // 返回购物车信息
                    respVo.setResult(URLEncoder.encode(JSON.toJSONString(buyerCart), "UTF-8"));
                }
            }

            respVo.setCode(RespVo.CODE_SUCCESS);
            respVo.setMessage("成功");
        } catch (Exception e) {
            respVo.setCode(RespVo.CODE_ERROR);
            respVo.setMessage("失败");
            log.error("移除购物项失败", e);
        }
        return respVo;
    }

    /**
     * 描述：清空购物车
     * 作者：张润泽
     * 时间：2019年8月27日 下午8:14:58
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping("/clearCar")
    @ResponseBody
    public RespVo clearCar(HttpServletRequest request, HttpServletResponse response) {
        RespVo respVo = new RespVo();
        try {
            Customer loginCustomer = getLoginCustomer( request);
            // 清空redis
            if (loginCustomer != null) {
                redisService.hdel(RedisConstant.BUYER_CAR_KEY, loginCustomer.getId());
            }
            //清空Cookie
            Cookie cookie = new Cookie(Constants.BUYER_CART, null);
            cookie.setPath("/");
            cookie.setMaxAge(0);
            response.addCookie(cookie);

            respVo.setCode(RespVo.CODE_SUCCESS);
            respVo.setMessage("成功");
        } catch (Exception e) {
            respVo.setCode(RespVo.CODE_ERROR);
            respVo.setMessage("失败");
            log.error("清空购物车失败", e);
        }
        return respVo;
    }

    /**
     * 描述：获取购物车
     * 作者：张润泽
     * 时间：2019年8月28日 下午6:20:51
     *
     * @param request
     * @param response
     * @return
     * @throws UnsupportedEncodingException
     * @throws LoginExecption
     */
    private BuyerCart getBuyerCart(HttpServletRequest request, HttpServletResponse response)
            throws UnsupportedEncodingException, LoginExecption {
        BuyerCart buyerCart = null;
        //1、获取Cookie中的购物车
        Cookie[] cookies = request.getCookies();
        if (null != cookies && cookies.length > 0) {
            for (Cookie cookie : cookies) {
                if (Constants.BUYER_CART.equals(cookie.getName())) {
                    buyerCart = JSON.parseObject(URLDecoder.decode(cookie.getValue(), "UTF-8"), BuyerCart.class);
                    break;
                }
            }
        }

        Customer loginCustomer = getLoginCustomer( request);
        // 登录了
        if (loginCustomer != null) {
            //2、 购物车 有东西, 则将购物车的东西保存到Redis中
            if (null != buyerCart) {
                this.insertBuyerCartToRedis(buyerCart, loginCustomer.getId());
                //清空Cookie 设置存活时间为0, 立马销毁
                Cookie cookie = new Cookie(Constants.BUYER_CART, null);
                cookie.setPath("/");
                cookie.setMaxAge(0);
                response.addCookie(cookie);
            }
            //3、取出Redis中的购物车
            buyerCart = (BuyerCart) redisService.hget(RedisConstant.BUYER_CAR_KEY,
                    loginCustomer.getId() + "");
        }

        return buyerCart;
    }

    /**
     * 描述：保存购物车到Redis中
     * 作者：张润泽
     * 时间：2019年8月27日 下午6:38:44
     *
     * @param buyerCart
     * @param customerId
     */
    private void insertBuyerCartToRedis(BuyerCart buyerCart, Long customerId) {
        Object buyerCarJson = redisService.hget(RedisConstant.BUYER_CAR_KEY, customerId + "");

        // redis中有购物车信息，合并购物项后放入redis
        if (buyerCarJson != null) {
            BuyerCart redisBuyerCart = (BuyerCart) buyerCarJson;
            redisBuyerCart.addMerchant(buyerCart.getMerchants());
            redisService.hset(RedisConstant.BUYER_CAR_KEY, customerId + "", redisBuyerCart);
        }
        // redis中无购物车信息，则直接将购物车放入redis
        else {
            redisService.hset(RedisConstant.BUYER_CAR_KEY, customerId + "", buyerCart);
        }
    }
}
